<?php
namespace Home\Controller;
use Think\Controller;
/**
 * PHPExcel工具类 实现表格导入导出功能 ExcelController.class.php
 * 
 * @author  作者: 张壮
 * @since	Version 1.0.0
 *
 * ************************** 调用方式 **************************************
 *  1.Excel 转 数组   A('Tool/Excel') -> readExcel(文件) 返回数组 
 *  2.数组 转 Excel   A('Tool/Excel') -> writeExcel(数组,[数据后缀],[生成方式])
 *
 * *********************** 高级配置参数说明 *********************************
 * 		A.数据后缀配置: 
 *				选填 1 或 2 
 *				1:xlsx格式 2：xls格式 默认:1
 *		B.生成方式配置: 
 *				选填 1 或 2 
 *				1:下载 2：生成本地文件 默认:1
 *		C.下载位置配置: 
 *				默认 ./  
 *				配置方式: A('Tool/Excel') -> write_dir = '';
 *		D.生成文件名配置: 
 *				默认:日期.后缀  如:2017-1-2.xlsx
 *				配置方式: A('Tool/Excel') -> excel_name = '';
 *		E.操作失败处理:
 *				处理失败 返回false
 *				获取报错信息: A('Tool/Excel') -> error;
 *
 * ******************************* 数组识别方式 *******************************
 *  
 *		$data = [
 *			0 => [字段1,字段2,字段3 ...],   --------------> 默认第一行为字段头
 *			1 => [值1,值2,值3 ...],         --------------> 值信息
 *			2 => [值1,值2,值3 ...],
 *			...
 *		];
 *
 */
class ExcelController extends Controller{
	/* 属性声明 */
	//报错信息
    private $error = null;
	//默认写入文件路径
	private $write_dir = './';
	//识别头部容错范围
	private $cat_field = 2;
	//生成文件名
	private $excel_name = null;


	/* 方法声明 */
	public function __construct(){
		//引入phpexcel工具类文件资源
		require_once './Org/PHPExcel/PHPExcel.php';
		$this -> excel_name = date('Y-m-d');
	}

	/**
	 * 解析excel文件
	 * @param string $excel_file excel文件
	 * @return mixed 解析成功返回数组 解析失败返回false
	 */
	public function readExcel($excel_file){
		//检测文件是否存在
		if(!file_exists($excel_file)){
			$this -> error('文件不存在!');
			return false;
		}
		$filePath = $excel_file;
		//初始化全局数据结果集
		$result = [];
		$PHPExcel = new \PHPExcel();
		$PHPReader = new \PHPExcel_Reader_Excel2007();
		if(!$PHPReader->canRead($filePath)){
			$PHPReader = new \PHPExcel_Reader_Excel5();
			if(!$PHPReader->canRead($filePath)){
				$this -> error('文件不存在!');
				return false;
			}
		}
		$PHPExcel = $PHPReader -> load($filePath);
		//读取excel文件中的第一个工作表
		$currentSheet = $PHPExcel -> getSheet(0);
		//取得最大的列号
		$allColumn = $currentSheet -> getHighestColumn();
		//取得一共有多少行
		$allRow = $currentSheet -> getHighestRow();
		//从第二行开始输出，因为excel表中第一行为列名
		for($currentRow = 1;$currentRow <= $allRow;$currentRow++){
			//初始化临时缓冲数组 记录每一行记录
			$buffer = [];
			//从第A列开始输出
			for($currentColumn= 'A';$currentColumn<= $allColumn; $currentColumn++){
				$val = 
				$currentSheet -> getCellByColumnAndRow(ord($currentColumn) - 65,$currentRow)		  ->getValue();
				$buffer[] = $val;
			}
			$result[] = $buffer;
		}
		//分析字段行是否存在
		$result = $this -> cat_data_head($result);
		return $result;
	}

	/**
	 * 识别表格头部
	 */
	private function cat_data_head($result){
		for($i=0;$i<$this->cat_field;$i++){
			foreach($result[$i] as $key => $v){
				if($v === null){
					unset($result[$i]);
					$result = array_values($result);
					break 2;
				}
			}
		}
		return $result;
	}

	/**
	 * 生成excel文件 要求:数组二维数组格式 第一元素为字段头部
	 *  $ary = array(
			0 => ['字段1','字段2','字段3' ...]
			1 => ['值1','值2','值3' ... ]
			...
	 	);
	 * @param array $data 被转换数组
	 * @param integer $prefix_type 生成文件格式 1为:xlsx格式 2为:xls格式 默认为 1
	 * @param integer $file_type 生成文件方式 1为下载 2为生成文件 默认下载
	 * @return 下载文件流
	 */
    public function writeExcel($prefix_type=1,$file_type=1){
		$file1 = './Org/Data/init_dic.json';
		$info = (json_decode(file_get_contents($file1),true));
		$info = $info['CASC.HR.DICT.ALL'];
		//dump($info);
		$arr = [];
		foreach($info as $k=>$v){
			$item = array_column($v['subitem'],'caption');
			$arr[$v['caption']] = $item;
		}

		//dump($arr);exit;
		$ccc = [];
		$i = 0;
		foreach($arr as $k=>$v){
			$ccc[$i][] = $k;

		}
		$s = 1;
		$d = 0;
		for($e=0;$e<count($arr);$e++){
			foreach($arr as $k=>$v){
				$ccc[$s][] = $v[$d]?$v[$d]:'空';
			}
			$s++;
			$d++;
		}
		$yy = [];
		foreach($ccc as $k=>$v){
			if($k<10){
				$yy[] = $v;
			}
		}
		//dump($result);exit;
		$vv = $yy[0];
		foreach($vv as $k=>$v){
			if($k<26){
				$result[0][] = $v;
			}
		}
		//dump($result);exit;
		//检测数组合法性
		if(!$this -> checkFile($result)){
			return false;
		};
		//导出表格数据
		//获取第一行 字段数据
		$field_row = $result[0];
		//生成表格头字段 A1 B1 C1
		$first_fields = $this -> createField();
		//生成主体表格字段 A B C
		$content_fields = $this -> createContentField();
		$objPHPExcel = new \PHPExcel();
		//Excel基本信息配置
		$objPHPExcel -> getProperties() -> setCreator('bjsasc')
			->setLastModifiedBy('bjsasc')
			->setTitle('bjsasc')
			->setSubject('bjsasc')
			->setDescription('bjsasc')
			->setKeywords('bjsasc')
			->setCategory('bjsasc');
		//循环设置表头信息
		$count = count($field_row);
		for($i=0;$i<$count;$i++){
			$objPHPExcel 
				-> setActiveSheetIndex(0) 
				-> setCellValue($first_fields[$i],$field_row[$i]);
		} 
		//循环表格数据体数据
		$offset = 2;
		//移除头信息
		array_shift($result);
		foreach($result as $k => $v){
			for($i=0;$i<$count;$i++){
				$objPHPExcel->setActiveSheetIndex(0) 
			   		-> setCellValue($content_fields[$i].$offset,$v[$i]);
			}
			$offset++;
		}
		$objPHPExcel -> getActiveSheet() -> setTitle('test');
		$objPHPExcel -> setActiveSheetIndex(0);
		$filename = $this -> excel_name;
		if($prefix_type==1){
			if($file_type==1){
				//下载xlsx文件
				header('Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
				header('Content-Disposition: attachment;filename="'.$filename.'.xlsx"');
				header('Cache-Control: max-age=0');
				$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel,'Excel2007');
				$objWriter -> save('php://output');
			}else{
				//生成xlsx文件
				$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel,'Excel2007');
				$objWriter -> save($this->write_dir . $filename.'.xlsx');
			}
		}else{
			if($file_type==1){
				//下载xls文件
				header('Content-Type: application/vnd.ms-excel');
				header('Content-Disposition: attachment;filename="'.$filename.'.xls"');
				header('Cache-Control: max-age=0');
				$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
				$objWriter -> save('php://output');
			}else{
				$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
				$objWriter -> save($this->write_dir . $filename.'.xls');
			}
		}
		exit;
	}

	/**
	 * 检测数组合法性
	 */
	private function checkFile($result){
		if(!is_array($result)){
			$this -> error = '数据格式非法!';
			return false;
		}
		//检测数组格式是否合法
		if(!count($result)){
			$this -> error = '元素为空!';
			return false;
		}
		$keys = array_keys($result);
		$values = array_values($result);
		if(!is_numeric($keys[0])){
			$this -> error = '数组下标非整数!';
			return false;
		}
		if(!is_array($values[0])){
			$this -> error = '数据格式非法!';
			return false;
		}
		return true;
	}

	/**
	 * 返回报错信息
	 * @return string 返回报错信息
	 */
	public function getError(){
		return $this -> error;
	}

	/**
	 * 生成excel序列集合 默认 A1-Z1
	 */
	private function createField(){
		$temp = range('A','Z');
		foreach($temp as $k => $v){
			$temp[$k] = $v . 1;
		}
		return $temp;
	}

	/**
	 * 生成excel数据体序列 A-Z
	 */
	private function createContentField(){
		return range('A','Z');
	}


	/**
	 * 魔术set方法
	 */
	public function __set($key,$v){
		if(!$this->$key){
			return false;
		}
		$this -> $key = $v;
	}

	/**
	 * 魔术get方法
	 */
	public function __get($key){
		if(!$this->$key){
			return false;
		}
		return $this -> $key;
	}

	/**
	 * 魔术get方法
	 */
	public function __call($method,$param){
		if(!function_exists($method)){
			die('访问不存在的方法!');
        }
	}
}